<?php

namespace App\Modules\Admin\Services\Water;

use App\Exceptions\Exception;
use App\Library\Junda\src\EquipmentService;
use App\Modules\Admin\Entities\Member\UsersWithApparatuses;
use App\Modules\Admin\Entities\Water\ApparatusElectricityLogModel;
use App\Modules\Admin\Entities\Water\ApparatusElectricityModel;
use App\Modules\Admin\Entities\Water\ApparatusPropertyFeeLogModel;
use App\Modules\Admin\Entities\Water\ApparatusPropertyFreeModel;
use App\Modules\Admin\Entities\Water\ApparatusWaterRateLogModel;
use App\Modules\Admin\Entities\Water\ApparatusWaterRateModel;
use App\Modules\Admin\Entities\Water\WaterDeviceModel;
use App\Modules\Admin\Entities\Water\WaterWithUserModel;
use App\Modules\Admin\Services\BaseService;
use Carbon\Carbon;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;

class WaterDeviceService extends BaseService
{


    const  WATER_MANAGE = 'manage';//水机管理人
    const  WATER_BUY = 'buy';//水机购买人
    public function __construct(WaterDeviceModel $model)
    {
        $this->model = $model;
        $this->WaterWithUserModel = new WaterWithUserModel();
        $this->with = ['community'];
        $this->detailWith = ['params_free','params_purify','params_seal'];
    }


    public function lists(array $params) : array
    {

        $params['where_callback'] = function($query) use ($params){
            $request = request();
            $search = $request->input('search', '');
            // 可以按照名称进行搜索
            if (!empty($search)){
                $query->where('water_title', 'LIKE', '%' . trim($search) . '%');
            }

            $community_id = $request->input('community_id', '');
            if(!empty($community_id)){
                $query->where('community_id',$community_id);
            }
            // 状态
            $status = $request->input('status', -1);
            if ($status > -1){
                $query->where('status', '=', $status);
            }
        };
        return parent::lists($params); // TODO: Change the autogenerated stub
    }

    public function getDeviceCache()
    {

    }


    public function getSelectLists($request){
        return $this->model->with($this->with)->where(function($query) use ($request){
            $search = $request->input('search', '');
            // 可以按照名称进行搜索
            if (!empty($search)){
                $query->where('water_title', 'LIKE', '%' . trim($search) . '%');
            }
            $community_id = $request->input('community_id', '');
            if (!empty($community_id)){
                $query->where('community_id',  trim($community_id));
            }
        })->orderBy($this->model->getKeyName(), 'ASC')->get(['water_id','water_title','code','mineral_title','rich_title','community_id','address','manage_profit_date'])->toArray();
    }
    public function getUserSelectlists($params){
        $user_id = $params['userId'];
        $UserWithApparatuses =  $this->WaterWithUserModel
            ->where(['user_id'=>$user_id,'is_delete'=>0])
            ->get(['water_id','water_role'])->toArray();
        $apparatuses_role = array_column($UserWithApparatuses,'water_role','water_id');

        $list =   $this->model->with(['community'])->whereIn('water_id',array_column($UserWithApparatuses,'water_id'))
            ->get(['water_id','water_title','mineral_title','code','rich_title','community_id','address','manage_profit_date'])->toArray();

        foreach ($list as $value=>&$item){
            $item['water_role'] = $apparatuses_role[$item['water_id']];
            $item['sum_score'] = 0;
            $item['proportion'] = 0;
            $item['score'] = 0;
        }

        return $list;
    }
    public function details($params)
    {
        $id = $params['id'];
        $res = $this->model->detail($id, '*', false);
        $equipment_id = $res['equipment_id'];
        $equipment_id_rich = $res['equipment_id_rich'];
        $FeeParam = EquipmentService::GetEquipmentFeeParam($equipment_id);
        $FeeParam_rich = EquipmentService::GetEquipmentFeeParam($equipment_id_rich);

        $insert = $FeeParam['data'];
        $insert_rich = $FeeParam_rich['data'];
//        $insert['apparatuses_id'] = $id;
//        unset($insert['Id']);
//        unset($insert['Name']);
//        unset($insert_rich['Id']);
//        unset($insert_rich['Name']);
//        EquipmentParamsModel::getInstance()->create($insert);
//        EquipmentParamsModel::getInstance()->create($insert_rich);

        exit(json_encode([$FeeParam,$FeeParam_rich]));

        exit(json_encode($FeeParam));
        return [];
    }

    public  function getJundaSelectlists()
    {
        $list = EquipmentService::GetEquipmentList();
        return $list['rows'];
    }



    public function create(array $params)
    {
        $params['mineral_title'] = "富氢水";
        DB::beginTransaction();
        try{
            parent::create($params); // TODO: Change the autogenerated stub
            DB::commit();
            return true;
        }catch (Exception $e){
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }
    public function update(array $params)
    {
        $equipment_id = $params['equipment_id'];
        $mineral_title = $params['mineral_title'];
        $mid = $params['mid'];
        $equipment_id_rich = $params['equipment_id_rich'];
        $mid_rich = $params['mid_rich'];
        $rich_title = $params['rich_title'];

        DB::beginTransaction();
        try{
//            $response_mineral = EquipmentService::UpdateEquipName($mid,$mineral_title);
//            if ($response_mineral['success']==false){
//                $this->error='修改失败，设备不存在，设备编号【'.$mid.'】';
//                DB::rollBack();
//                return false;
//            }
//            $response_rich = EquipmentService::UpdateEquipName($mid_rich,$rich_title);
//            if ($response_rich['success']==false){
//                $this->error='修改失败，设备不存在，设备编号【'.$mid_rich.'】';
//                DB::rollBack();
//                return false;
//            }
            parent::update($params); // TODO: Change the autogenerated stub
            DB::commit();
            return true;
        }catch (Exception $e){
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }
    public function updatedbjd($params)
    {
        $mineral_title = $params['mineral_title'];
        $mid = $params['mid'];
        $mid_rich = $params['mid_rich'];
        $rich_title = $params['rich_title'];
        DB::beginTransaction();
        try{
            $response_mineral = EquipmentService::UpdateEquipName($mid,$mineral_title);
            if ($response_mineral['success']==false){
                $this->error='修改失败，设备不存在，设备编号【'.$mid.'】';
                DB::rollBack();
                return false;
            }
            $response_rich = EquipmentService::UpdateEquipName($mid_rich,$rich_title);
            if ($response_rich['success']==false){
                $this->error='修改失败，设备不存在，设备编号【'.$mid_rich.'】';
                DB::rollBack();
                return false;
            }
            parent::update($params); // TODO: Change the autogenerated stub
            DB::commit();
            return true;
        }catch (Exception $e){
            DB::rollBack();
            throw new Exception($e->getMessage());
        }
    }
    // 单条数据
    public function show($params){

        $id = $params['id'];
        $info = $this->model->where(['id'=>$id])->first();

        if (empty($info)) {
            $this->error='数据不存在';
            return false;
        }
        $time = date("Y-m-d",strtotime('+15 day'));//提前15天通知
        //物业费
        if($info->property_fee_time<$time) {
            $propertyFee = 0;
        }else{
            $propertyFee = $info->property_fee;
        }
        //水费
        if($info->water_rate_time<$time) {
            $waterRate = 0;
        }else{
            $waterRate = $info->water_rate;
        }
        //电费
        if($info->electricity_time<$time) {
            $electricity = 0;
        }else{
            $electricity = $info->electricity;
        }

        return [
            'water_id' => $info->water_id,
            'water_title' => $info->water_title,
            'code' => $info->code,
            'user_info' => [
                'type' => $info->type,
                'id' => $info->buy_user_id,
                'nickname' => Arr::get($info,'user.nickname','')
            ],
            'community_info' => [
                'id' => Arr::get($info,'community.id',0),
                'title' => Arr::get($info,'community.title',''),
            ],
            'signed_at' => $info->signed_at,
            'price' => [
                'property_fee' => $propertyFee/100,//单位：分
                'electricity' => $electricity/100,
                'water_rate' => $waterRate/100,
            ]
        ];
    }


    public function bindUser($params){

        return $this->update($params);
    }
    public function signUser($params){

        return $this->update($params);
    }
    public function updatePropertyFee($params)
    {
        $id = $params['id'];
        $price = $params['price'];
        $apparatusInfo = $this->model->where(['id'=>$id])->first();

        if (empty($apparatusInfo)) {
            $this->error='数据不存在';
            return false;
        }

        $startedAt = date("Y-m-d",time());
        $endedAt = date("Y-m-d",strtotime('+1 year'));

        $pfm_update_data['price'] = $price*100;


        $orm = new ApparatusPropertyFreeModel();
        $orm->price = $price*100;
        $orm->apparatus_id = $id;
        $orm->type =
        $orm->started_at = $startedAt;
        $orm->ended_at = $endedAt;
        DB::beginTransaction();
        $bool = $orm->save();
        if (!$bool) {
            DB::rollBack();
            $this->error='添加出错';
            return false;
        }
        $apparatusInfo->property_fee_time = $endedAt;
        $apparatusInfo->property_fee = $price*100;
        $bool = $apparatusInfo->save();
        if (!$bool) {
            DB::rollBack();
            $this->error='添加出错';
            return false;
        }
        self::monthlyPriceSave($price*100,'year',$id,$startedAt,new ApparatusPropertyFeeLogModel());
        DB::commit();
        return true;
    }
    public function updateElectricity($params){

        $id = $params['id'];
        $price = $params['price'];
        $apparatusInfo = $this->model->where(['id'=>$id])->first();

        if(empty($apparatusInfo)) {
            $this->error='设备不存在';
            return false;
        }
        [$startedAt,$endedAt] = getQuarterStartAndEnd(date("Y-m"));
        $orm = new ApparatusElectricityModel();
        DB::beginTransaction();
        $bool = $this->quarterPriceSave($price, $orm, $id, $startedAt, $endedAt);
        if (!$bool) {
            DB::rollBack();
            $this->error='记录出错';
            return false;
        }
        $apparatusInfo->electricity = $price*100;
        $apparatusInfo->electricity_time = $endedAt;
        $bool = $apparatusInfo->save();
        if (!$bool) {
            DB::rollBack();
            $this->error='记录出错';
            return false;
        }
        self::monthlyPriceSave($price*100,'quarter',$id,$startedAt,new ApparatusElectricityLogModel());
        DB::commit();
        return true;
    }
    public function updateWaterRate($params){

        $id = $params['id'];
        $price = $params['price'];
        $apparatusInfo = $this->model->where(['id'=>$id])->first();

        if(empty($apparatusInfo)) {
            $this->error='设备不存在';
            return false;
        }
        [$startedAt,$endedAt] = getQuarterStartAndEnd(date("Y-m"));
        $orm = new ApparatusWaterRateModel();
        DB::beginTransaction();
        $bool = $this->quarterPriceSave($price, $orm, $id, $startedAt, $endedAt);
        if(!$bool) {
            DB::rollBack();
            $this->error='记录出错';
            return false;
        }
        $apparatusInfo->water_rate = $price*100;
        $apparatusInfo->water_rate_time = $endedAt;
        $bool = $apparatusInfo->save();
        if (!$bool) {
            DB::rollBack();
            $this->error='记录出错';
            return false;
        }
        self::monthlyPriceSave($price*100,'quarter',$id,$startedAt,new ApparatusWaterRateLogModel());
        DB::commit();
        return true;
    }

    /**
     * @param $price
     * @param ApparatusElectricity|ApparatusWaterRate $orm
     * @param $id
     * @param string $startedAt
     * @param string $endedAt
     * @return true
     */
    protected function quarterPriceSave($price, ApparatusElectricityModel|ApparatusWaterRateModel $orm,
                                        $id, string $startedAt, string $endedAt): bool
    {
        $orm->price = $price*100;//单位：分
        $orm->apparatus_id = $id;
        $orm->type = 'quarter';
        $orm->started_at = $startedAt;
        $orm->ended_at = $endedAt;
        return $orm->save();
    }
    /**
     * @param int $price 单位：分
     * @param $type
     * @param $apparatusId
     * @param $startTime
     * @return true
     */
    protected function monthlyPriceSave(int $price,$type,$apparatusId,$startTime,
                                        ApparatusElectricityLogModel|ApparatusPropertyFeeLogModel|ApparatusWaterRateLogModel $orm): true
    {
        if($type == 'year') {
            $max = 12;
        }else{
            $max = 3;
        }
        $average = floor($price/$max);
        $sum = 0;
        for ($i = 1;$i <= $max;$i++) {
            if ($i == $max) { // 最后一个月进行差值合并
                $newPrice = $price - $sum;
            } else {
                $newPrice = $average;
                $sum += $average; // 计算已分配的总额
            }
            $newOrm = clone $orm;
            $date = Carbon::parse($startTime)->addMonths($i-1)->toDateString();
            $newOrm->price = $newPrice;
            $newOrm->apparatus_id = $apparatusId;
            $newOrm->date = $date;
            $newOrm->save();
        }
        return true;
    }
    /**
     * @param $communityId
     * @return int
     */
    public function getFacilityCount($communityId): int
    {
        return $this->model->where('community_id',$communityId)->count();
    }
    /**
     * @param $userId
     * @param $communityId
     * @return int
     */
    public function getUserCommunityApparatusCount($userId, $communityId): int
    {
        return $this->model->where('community_id',$communityId)->where('user_id',$userId)->count();
    }

    /**
     * @param $userId
     * @return array
     */
    public function getUserAllApparatusCount($userId): array
    {
        $count = $this->model->where('user_id',$userId)->count();
        return ['count' => $count];
    }
}
